home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / scheme / schematk / src_1152.lha / Doc.subproj / DocWin.m < prev    next >
Encoding:
Text File  |  1993-02-25  |  11.5 KB  |  437 lines

  1. /* Copyright รก 1991 Gustavus Adolphus College.  All rights reserved.
  2.  *
  3.  * Schematik was developed by Gustavus Adolphus College (GAC) with
  4.  * support from NeXT Computer, Inc.  Permission to copy this software,
  5.  * to redistribute it, and to use it for any purpose is granted,
  6.  * subject to the following restrictions and understandings.
  7.  *
  8.  * 1. Any copy made of this software must include this copyright
  9.  * notice in full.
  10.  *
  11.  * 2. Users of this software agree to make their best efforts (a) to
  12.  * return to the GAC Mathematics and Computer Science Department any
  13.  * improvements or extensions that they make, so that these may be
  14.  * included in future releases; and (b) to inform GAC of noteworthy
  15.  * uses of this software.
  16.  *
  17.  * 3. All materials developed as a consequence of the use of this
  18.  * software shall duly acknowledge such use, in accordance with the
  19.  * usual standards of acknowledging credit in academic research.
  20.  *
  21.  * 4. GAC makes no express or implied warranty or representation of
  22.  * any kind with respect to this software, including any warranty
  23.  * that the operation of this software will be error-free.  ANY
  24.  * IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
  25.  * PURPOSE IS HEREBY DISCLAIMED.  GAC is under no obligation to
  26.  * provide any services, by way of maintenance, update, or otherwise.
  27.  *
  28.  * 5. In conjunction with products arising from the use of this
  29.  * material, there shall be no use of the name of Gustavus Adolphus
  30.  * College nor of any adaptation thereof in any advertising,
  31.  * promotional, or sales literature without prior written consent
  32.  * from GAC in each case.
  33.  */
  34.  
  35. #import "DocWin.h"
  36. #import "../defines.h"
  37. #import DocText_h
  38. #import PrefAgent_h
  39. #import Main_h
  40. #import <appkit/OpenPanel.h>
  41. #import <appkit/ScrollView.h>
  42. #import <appkit/Text.h>
  43. #import <objc/List.h>
  44. #import <streams/streams.h>
  45. #import <sys/malloc.h>
  46. #import <sys/stat.h>
  47. #import <mach.h>
  48. #import <NXCType.h>
  49. #import <string.h>
  50.  
  51. extern char *stlchr(char *,int);
  52.  
  53. #define NIBFILE            "Doc.nib"
  54. #define MINIWINDOWICON        "Doc"
  55. #define DOCZONENAME        "DocWin"
  56. #define MINWINDOWHEIGHT        67
  57.  
  58. static id findOpenFile(id, id, char *);
  59.  
  60. @implementation DocWin
  61.  
  62. + new
  63. {
  64.     NXZone *zone=NXCreateZone(vm_page_size, vm_page_size, YES);
  65.  
  66. DEBUG_FUNC1(DEBUGLEVEL);
  67.     DEBUG_ASSERT(zone!=NULL)
  68.     self = LoadNIB(NIBFILE, self, zone); 
  69.     DEBUG_ASSERT(self!=nil)
  70.     docZone = zone;
  71.     NXNameZone(docZone, DOCZONENAME);
  72.     [self _newAuxiliary];
  73.     [self setMiniwindowIcon:MINIWINDOWICON];
  74.     DEBUG_ASSERT(([self miniwindowIcon]!=NULL)&&(*[self miniwindowIcon]))
  75.     [self setTitleAsFilename:filename];
  76.     DEBUG_ASSERT(([self title]!=NULL)&&(*[self title]))
  77.     return self;
  78. }
  79.  
  80. + performOpenFromFile:(char *)aString
  81. {
  82.     NXStream *stream;
  83.     BOOL freeString=NO;
  84.  
  85. DEBUG_FUNC1(DEBUGLEVEL);
  86.     if (aString==NULL)
  87.       {
  88.         id openPanel=[OpenPanel new];
  89.         char *types[]={DOCUMENTEXTENSION, DOCUMENTEXTENSION BACKUPEXTENSION, NULL};
  90.     char *temp;
  91.  
  92.         DEBUG_ASSERT(openPanel!=nil)
  93.         [openPanel allowMultipleFiles:NO];
  94.         {id mainWin = [NXApp mainWindow];
  95.          const char *fn;
  96.          if(mainWin == nil || ![mainWin isKindOf:self])
  97.            fn = [[NXApp interactionWindow] filename];
  98.          else{
  99.            fn = [mainWin filename];
  100.          }
  101.          [openPanel setDirectory:temp=stlchr(NXCopyStringBuffer(fn), PATHSEPARATOR)];
  102.         }
  103.     free(temp);
  104.         if ([openPanel runModalForTypes:types]&&[openPanel filename]&&*[openPanel filename])
  105.           {
  106.             aString = NXCopyStringBuffer([openPanel filename]);
  107.             DEBUG_ASSERT((aString!=NULL)&&(*aString))
  108.             freeString = YES;
  109.           }
  110.         else
  111.           return nil;
  112.       }
  113.     DEBUG_ASSERT((aString!=NULL)&&(*aString))
  114.     if (self = findOpenFile(self, NXApp, aString))
  115.       {
  116.         [self makeKeyAndOrderFront:self];
  117.         if (freeString) free(aString);
  118.         return nil;
  119.       }
  120.     DEBUG_ASSERT(self==nil)
  121.     if (stream = NXMapFile(aString, NX_READONLY))
  122.       {
  123.         self = [DocWin new];
  124.         [self setFilename:aString];
  125.         DEBUG_ASSERT((filename!=NULL)&&(*filename))
  126.         [self setTitleAsFilename:filename];
  127.         [textView readText:stream];
  128.         NXCloseMemory(stream, NX_FREEBUFFER);
  129.         [textView setSel:0 :0];
  130.         named = YES;
  131.         if (freeString) free(aString);
  132.         return self;
  133.       }
  134.     NXRunAlertPanel(OPENALERTTITLE, FILEOPENERROR, NULL, NULL, NULL);
  135.     if (freeString) free(aString);
  136.     return nil;
  137. }
  138.  
  139. - makeKeyAndOrderFront:sender
  140. {
  141. DEBUG_FUNC1(DEBUGLEVEL);
  142.     [super makeKeyAndOrderFront:sender];
  143.     [super makeFirstResponder:textView];
  144.     [textView lockFocus];
  145.     [textView showCaret];
  146.     [textView unlockFocus];
  147.     return self;
  148. }
  149.  
  150. - free
  151. {
  152. DEBUG_FUNC1(DEBUGLEVEL);
  153.     if (filename)
  154.       NXZoneFree(docZone, filename);
  155.     return [super free];
  156. }
  157.  
  158. - performFormat:sender
  159. {
  160. DEBUG_FUNC1(DEBUGLEVEL);
  161.     [textView formatTextSelectionOnly:NO];
  162.     return self;
  163. }
  164.  
  165. - performRevert:sender
  166. {
  167.     NXStream *stream;
  168.  
  169. DEBUG_FUNC1(DEBUGLEVEL);
  170.     if (named&&wFlags2.docEdited&&(NXRunAlertPanel(REVERTALERTTITLE, REVERTALERTQUERY, REVERTALERTDEFAULT, REVERTALERTALTERNATE, NULL, (strrchr(filename,'/')+1))==NX_ALERTDEFAULT))
  171.       {
  172.         if (stream = NXMapFile(filename, NX_READONLY))
  173.           {
  174.             [super disableFlushWindow];
  175.             [textView readText:stream];
  176.             NXCloseMemory(stream, NX_FREEBUFFER);
  177.             [[[super display] reenableFlushWindow] flushWindow];
  178.             [super setDocEdited:NO];
  179.             [textView setSel:0 :0];
  180.             return self;
  181.           }
  182.         NXRunAlertPanel(REVERTALERTTITLE, FILEOPENERROR, NULL, NULL, NULL);
  183.       }
  184.     return self;
  185. }
  186.  
  187. - performSave:sender
  188. {
  189.     NXStream *stream;
  190.  
  191. DEBUG_FUNC1(DEBUGLEVEL);
  192.     if (!named)
  193.       return [self performSaveAs:self];
  194.     if (stream = NXOpenMemory(NULL, 0, NX_WRITEONLY))
  195.       {
  196.         [self _saveAuxiliary:stream filename:filename];
  197.         return self;
  198.       }
  199.     NXRunAlertPanel(SAVEALERTTITLE, FILESAVEERROR, NULL, NULL, NULL);
  200.     return self;
  201. }
  202.  
  203. - performSaveAs:sender
  204. {
  205.     NXStream *stream;
  206.     id savePanel = [SavePanel new];
  207.     char *temp;
  208.  
  209. DEBUG_FUNC1(DEBUGLEVEL);
  210.     DEBUG_ASSERT(savePanel!=nil)
  211.     [savePanel setRequiredFileType:DOCUMENTEXTENSION];
  212.         {id mainWin = [NXApp mainWindow];
  213.          const char *fn;
  214.          if(mainWin == nil || ![mainWin isKindOf:self])
  215.            fn = [[NXApp interactionWindow] filename];
  216.          else{
  217.            fn = [mainWin filename];
  218.          }
  219.     if ([savePanel runModalForDirectory:temp=stlchr(NXCopyStringBuffer(fn), PATHSEPARATOR) file:(strrchr(fn, PATHSEPARATOR)+1)]&&[savePanel filename]&&*[savePanel filename])
  220.       {
  221.         if (stream = NXOpenMemory(NULL, 0, NX_WRITEONLY))
  222.           {
  223.         named=NO;
  224.             [self _saveAuxiliary:stream filename:(char *)[savePanel filename]];
  225.         free(temp);
  226.             return self;
  227.           }
  228.         NXRunAlertPanel(SAVEALERTTITLE, FILESAVEERROR, NULL, NULL, NULL);
  229.       }
  230.     }
  231.     free(temp);
  232.     return self;
  233. }
  234.  
  235. - undo:sender
  236. {
  237. DEBUG_FUNC1(DEBUGLEVEL);
  238.     return self;
  239. }
  240.  
  241. - print:sender
  242. {
  243. DEBUG_FUNC1(DEBUGLEVEL);
  244.     return [[self textView] printPSCode:self];
  245. }
  246.  
  247. - (id)scrollView
  248. {
  249. DEBUG_FUNC1(DEBUGLEVEL);
  250.     return scrollView;
  251. }
  252.  
  253. - (id)textView
  254. {
  255. DEBUG_FUNC1(DEBUGLEVEL);
  256.     return textView;
  257. }
  258.  
  259. - (const char *)filename
  260. {
  261. DEBUG_FUNC1(DEBUGLEVEL);
  262.     return filename;
  263. }
  264.  
  265. - setFilename:(const char *)aString
  266. {
  267. DEBUG_FUNC1(DEBUGLEVEL);
  268.     if (filename!=NULL)
  269.       NXZoneFree(docZone, filename);
  270.     filename = NXCopyStringBufferFromZone(aString, docZone);
  271.     DEBUG_ASSERT(filename!=NULL)
  272.     return self;
  273. }
  274.  
  275. - (BOOL)named
  276. {
  277. DEBUG_FUNC1(DEBUGLEVEL);
  278.     return named;
  279. }
  280.  
  281. - setNamed:(BOOL)aBoolean
  282. {
  283. DEBUG_FUNC1(DEBUGLEVEL);
  284.     named = aBoolean;
  285.     return self;
  286. }
  287.  
  288. @end
  289.  
  290. @implementation DocWin (Delegate)
  291.  
  292. - textDidGetKeys:sender isEmpty:(BOOL)flag
  293. {
  294. DEBUG_FUNC1(DEBUGLEVEL);
  295.     if (!wFlags2.docEdited)
  296.       [super setDocEdited:YES];
  297.     return self;
  298. }
  299.  
  300. - windowWillClose:sender
  301. {
  302. DEBUG_FUNC1(DEBUGLEVEL);
  303.     if (wFlags2.docEdited&&[[PrefAgent new] confirmOnClose])
  304.       {
  305.         int i = NXRunAlertPanel(SAVEALERTTITLE, SAVEALERTQUERY, SAVEALERTDEFAULT, SAVEALERTALTERNATE, SAVEALERTOTHER, (strrchr(filename,'/')+1));
  306.  
  307.         if (i==NX_ALERTOTHER)
  308.           return nil;
  309.         if (i==NX_ALERTDEFAULT)
  310.           if (!named)
  311.             return [self performSaveAs:self];
  312.           else
  313.             return [self performSave:self];
  314.       }
  315.     return self;
  316. }
  317.  
  318. - windowWillResize:sender toSize:(NXSize *)frameSize
  319. {
  320. DEBUG_FUNC1(DEBUGLEVEL);
  321.     if (frameSize->height<MINWINDOWHEIGHT)
  322.       frameSize->height = MINWINDOWHEIGHT;
  323.     return self;
  324. }
  325.  
  326. @end
  327.  
  328. @implementation DocWin (Private)
  329.  
  330. - (void)_newAuxiliary
  331. {
  332.     NXRect r;
  333.  
  334. DEBUG_FUNC1(DEBUGLEVEL);
  335.     [self useOptimizedDrawing:YES];
  336.     [[scrollView docView] getFrame:&r];
  337.     [scrollView setVertScrollerRequired:YES];
  338.     [scrollView setHorizScrollerRequired:NO];
  339.     [scrollView setDynamicScrolling:YES];
  340.     textView = [[DocText allocFromZone:docZone] initFrame:&r];
  341.     DEBUG_ASSERT(textView!=nil)
  342.     [textView moveTo:0.0 :0.0];
  343.     [textView notifyAncestorWhenFrameChanged:YES];
  344.     [textView setVertResizable:YES];
  345.     [textView setSelectable:YES];
  346.     [textView setEditable:YES];
  347.     if ([[PrefAgent new] reverseVideo])
  348.       {
  349.     [textView setBackgroundGray:NX_BLACK];
  350.     [scrollView setBackgroundGray:NX_BLACK];
  351.     [textView setTextGray:NX_WHITE];
  352.       }
  353.     [textView setAutosizing:NX_WIDTHSIZABLE];
  354.     r.size.height = 0.0;
  355.     [textView setMinSize:&r.size];
  356.     r.size.height = 1.0e30;
  357.     [textView setMaxSize:&r.size];
  358.     [[scrollView setDocView:textView] free];
  359.     [scrollView setLineScroll:[textView lineHeight]];
  360.     [scrollView setPageScroll:[textView lineHeight]];
  361.     [textView setDelegate:self];
  362.     filename = NXCopyStringBufferFromZone(DEFAULTFILENAME, docZone);
  363.     DEBUG_ASSERT(filename!=NULL)
  364.     named = NO;
  365. }
  366.  
  367. - (void)_saveAuxiliary:(NXStream *)stream filename:(char *)file
  368. {
  369.     NXSelPt start,end;
  370.     char temp[1040],*temp2;
  371.  
  372. DEBUG_FUNC1(DEBUGLEVEL);
  373.     [textView getSel:&start :&end];
  374.     temp2 = NXCopyStringBuffer([super title]);
  375.     sprintf(temp, SAVINGMESSAGE, file);
  376.     [super setTitle:temp];
  377.     NXPing();
  378.     [textView writeText:stream];
  379.     if (!hasBackup&&[[PrefAgent new] keepBackupCopy])
  380.       {
  381.         struct stat buf;
  382.     stat(file,&buf);
  383.         if (buf.st_nlink>1)
  384.       {
  385.         NXStream *bstream;
  386.         char *tempfile=NXCopyStringBuffer(file);
  387.         tempfile = (char *)realloc(tempfile,strlen(file)+2);
  388.         strcat(tempfile,BACKUPEXTENSION);
  389.         if (bstream = NXMapFile(file,NX_READONLY))
  390.           {
  391.             NXSaveToFile(bstream,tempfile);
  392.             NXCloseMemory(bstream, NX_FREEBUFFER);
  393.               }
  394.         free(tempfile);
  395.       }
  396.     else
  397.       {
  398.         char *tempfile=NXCopyStringBuffer(file);
  399.         tempfile = (char *)realloc(tempfile,strlen(file)+2);
  400.         strcat(tempfile,BACKUPEXTENSION);
  401.         rename(file,tempfile);
  402.         free(tempfile);
  403.       }
  404.     hasBackup=YES;
  405.       }
  406.     if (NXSaveToFile(stream, file)<0)
  407.       {
  408.         NXRunAlertPanel(SAVEALERTTITLE, SAVEERRORMESSAGE, OKSTRING, NULL, NULL);
  409.     [super setTitle:temp2];
  410.       }
  411.     else
  412.       {
  413.         [super setDocEdited:NO];
  414.         if (!named) 
  415.       [self setFilename:file];
  416.         [self setTitleAsFilename:filename];
  417.         named = YES;
  418.       }
  419.     [textView setSel:start.cp :end.cp];
  420.     NXCloseMemory(stream, NX_FREEBUFFER);
  421.     free(temp2);
  422. }
  423.  
  424. @end
  425.  
  426. id findOpenFile(id self, id NXApp, char * aString)
  427. {
  428.     id doc,winList=[NXApp windowList];
  429.     int i;
  430.  
  431.     DEBUG_ASSERT(winList!=nil)
  432.     for(i=[winList count]-1, doc=[winList objectAt:i]; i>=0; i--, doc=[winList objectAt:i])
  433.       if ([doc isMemberOf:self]&&(!NXOrderStrings((unsigned char *)[doc filename], (unsigned char *)aString, YES, -1, NULL)))
  434.         return doc;
  435.     return nil;
  436. }
  437.